<?php


namespace PKApp\Content;

use PKApp\Content\Classes\MakeHtml;
use PKApp\Content\Classes\TraitContent;
use PKApp\Model\Classes\TraitModel;
use PKCommon\Controller\AdminController;
use PKFrame\DataHandler\Arrays;
use PKFrame\DataHandler\Date;
use PKFrame\DataHandler\JSON;
use PKFrame\DataHandler\Numbers;
use PKFrame\Extend\Xml;

class AdminMakeHtml extends AdminController
{

    use TraitContent, TraitModel;

    protected $taskName;
    protected $count_category, $count_page_category, $count_content, $count_total;
    protected $finish_category, $finish_content, $finish_total;
    protected $now_category_index, $now_category_page, $now_category_contentCount, $now_speed, $now_is_makeHtml;
    protected $service_category;

    public function __construct()
    {
        parent::__construct();
        request()->get('siteId', $this->loginUser()->SiteId);
        $this->service_category = $this->serviceOfCategory($this->loginUser()->SiteId);
    }

    public function Main()
    {
        $this->fetch('make_html');
    }

    public function ApiByCount()
    {
        $this->_modelByRequest();
        $this->count_content = $this->count_page_category = 0;
        $list_id = [];
        foreach (request()->post('id') as $item) {
            Numbers::IsId($item) == false ?: $list_id[] = $item;
        }
        $list_category = $this->service_category->GetListById($list_id);
        Arrays::Is($list_category) ?: $this->noticeByJson('Category_Empty');
        foreach ($list_category as $item_entity) {
            $this->countCategoryAndContent($item_entity);
        }
        $this->count_total = $this->count_page_category + $this->count_content;
        $this->_modelByOut();
    }

    /**
     * 统计当前栏目的内容总数据及栏目页总数
     * @param $entity_category
     */
    protected function countCategoryAndContent($entity_category)
    {
        switch ($entity_category['categoryType']) {
            case 'list':
                $is_children = !empty($entity_category['childrenIdList']);
                $count_content = $this->serviceOfContent(
                    $entity_category['modelId']
                )->GetCount([
                    'siteId' => $this->loginUser()->SiteId,
                    'catId' => ($is_children ? $entity_category['childrenIdList'] : $entity_category['id'])
                ]);
                // 如果不是父级栏目，则直接叠加内容数量
                $is_children ?: $this->count_content += $count_content;
                $this->service_category->UpdateById($entity_category['id'], ['countContent' => $count_content]);
                // 列表页数
                $set_lineNumber = Numbers::To($entity_category['template']['listDataSize']);
                $this->count_page_category += $set_lineNumber == 0 ? 1 : max(ceil($count_content / $set_lineNumber), 1);
                break;
            case 'link';
            case 'page':
                $this->count_page_category += 1;
                break;
        }
    }

    public function ApiByCreate()
    {
        $this->_modelByRequest();
        $list_id = request()->post('id');
        ($count_id = Arrays::Is($list_id)) > 0 ?: $this->noticeByJson('Category_idEmpty');
        if (($this->now_category_index < $count_id) && ($this->count_category == $count_id)) {
            $this->_handler_category(
                $this->service_category->interface_getEntityById(
                    $list_id[$this->now_category_index]
                )
            );
        } else {
            $this->noticeByJson('MakeHtml_Index_Error');
        }
    }

    /**
     * 栏目更新分组执行
     * @param $entity_category
     */
    private function _handler_category($entity_category)
    {
        $this->now_speed = [
            'name' => $entity_category['name'],
        ];
        $set_tpl = $entity_category['template'];
        switch ($entity_category['categoryType']) {
            case 'list':
                $is_children = !empty($entity_category['childrenIdList']);
                $count_content = $entity_category['countContent'];
                $set_lineNumber = Numbers::To($entity_category['template']['listDataSize']);
                $count_listPage = $set_lineNumber == 0 ? 1 : max(ceil($count_content / $set_lineNumber), 1);

                // 开始比较
                if ($this->now_category_page < $count_listPage) {
                    $this->now_speed['makeType'] = 'category_list';
                    // 判断是否发布列表页
                    $this->now_is_makeHtml = !empty(Arrays::GetKey('categoryHtml', $set_tpl)) && !empty(Arrays::GetKey('categoryUrl', $set_tpl));
                    if ($this->now_is_makeHtml == false) {
                        $this->finish_category += $count_listPage;
                        $this->finish_total += $count_listPage;
                        $this->now_category_page = $count_listPage;
                    } else {
                        $line = 1;
                        // 该变量也是发布静态的页码
                        $this->now_category_page += $line;
                        $this->_makeHtmlByCategory($entity_category);
                        $this->finish_category += $line;
                        $this->finish_total += $line;
                    }
                } elseif ($this->now_category_contentCount < $count_content) {
                    // 当栏目下的内容页的页数小于总页数时执行
                    $this->now_speed['makeType'] = 'content';
                    $this->now_is_makeHtml = !empty(Arrays::GetKey('contentHtml', $set_tpl)) && !empty(Arrays::GetKey('contentUrl', $set_tpl));
                    if ($this->now_is_makeHtml == false) {
                        $this->finish_content += $count_content;
                        $this->finish_total += $count_content;
                        $this->now_category_contentCount = $count_content;
                    } else {
                        $this->_makeHtmlByContent($entity_category);
                    }
                }

                if ($is_children) {
                    // 父级栏目，只产生列表页
                    if (($this->now_category_page >= $count_listPage)) {
                        $this->now_category_index += 1;
                        $this->now_category_page = 0;
                    }
                } else {
                    if (($this->now_category_page == $count_listPage)
                        && ($this->now_category_contentCount == $count_content)) {
                        // 当遍历栏目的数量大于（等于）总数时
                        // 当遍历栏目所属的内容数量大于（等于）总数时
                        $this->now_category_index += 1;
                        $this->now_category_page = 0;
                        $this->now_category_contentCount = 0;
                    }
                }
                break;
            case 'page':
                $this->now_speed['makeType'] = 'category_page';
                $this->now_is_makeHtml = !empty(Arrays::GetKey('pageHtml', $set_tpl)) && !empty(Arrays::GetKey('pageUrl', $set_tpl));
                if ($this->now_is_makeHtml) {
                    $this->_makeHtmlByCategory($entity_category);
                }
                $this->now_category_index += 1;
                $this->finish_category += 1;
                $this->finish_total += 1;
                break;
            case 'link':
                $this->now_speed['makeType'] = 'category_link';
                $this->finish_category += 1;
                $this->now_category_index += 1;
                $this->finish_total += 1;
                break;
            default:
                $this->noticeByJson('Category_TypeEmpty');
                break;
        }
        $this->_modelByOut();
    }

    //列表页更新
    private function _makeHtmlByCategory($entity_category)
    {
        $cls_make = new MakeHtml($entity_category);
        $cls_make->Category($this->now_category_page);
    }

    //内容页更新
    private function _makeHtmlByContent($entity_category)
    {
        $line = 1;
        $set_tpl = $entity_category['template'];
        $this->now_is_makeHtml = !empty(Arrays::GetKey('contentHtml', $set_tpl)) && !empty(Arrays::GetKey('contentUrl', $set_tpl));
        if ($this->now_is_makeHtml) {
            $this->now_category_contentCount += $line;
            $entity_content = $this->_eachMakeContentOfPage($entity_category);
            // 镜像内容不能被静态化
            if (!(array_key_exists('mirroringId', $entity_content) && Numbers::IsId($entity_content['mirroringId']))) {
                $cls_make = new MakeHtml($entity_category);
                $cls_make->Content($entity_content);
                if (array_key_exists('pageSize', $entity_content)) {
                    for ($i = 2; $i <= $entity_content['pageSize']; $i++) {
                        $entity_content = $this->_eachMakeContentOfPage($entity_category, $i);
                        $cls_make->Content($entity_content, $i);
                    }
                }
            }
            $this->finish_content += $line;
            $this->finish_total += $line;
            $this->now_speed['name'] = $entity_content['title'];
        }
    }

    private function _eachMakeContentOfPage(array $entity_category, int $page = null): array
    {
        is_null($page) ?: request()->get('page', $page);
        return $this->serviceOfContent(
            $entity_category['modelId']
        )->GetEntityByPageIndex($this->now_category_contentCount, [
            'catId' => $entity_category['id'],
            'siteId' => $entity_category['siteId']
        ]);
    }

    private function _modelByParamsList(): array
    {
        return [
            'count_category', 'count_page_category', 'count_content', 'count_total',
            'finish_total', 'finish_category', 'finish_content',
            'now_category_index', 'now_category_page', 'now_category_contentCount'
        ];
    }

    private function _modelByRequest()
    {
        $this->taskName = request()->post('taskName');
        $list_params = $this->_modelByParamsList();
        switch (request()->action()) {
            case 'ApiByCount';
                foreach ($list_params as $item_params) {
                    if (stristr($item_params, 'count_')) {
                        $this->{$item_params} = Numbers::To(request()->post($item_params));
                    } else {
                        $this->{$item_params} = 0;
                    }
                }
                break;
            case 'ApiByCreate';
                foreach ($list_params as $item_params) {
                    $this->{$item_params} = Numbers::To(request()->post($item_params));
                }
                break;
        }
    }

    private function _modelByOut()
    {
        $params = [];
        foreach ($this->_modelByParamsList() as $item_params) {
            $params[$item_params] = Numbers::To($this->{$item_params});
        }
        !Arrays::Is($this->now_speed) ?: $params = array_merge($params, $this->now_speed);
        if (request()->action() == 'ApiByCreate') {
            $params = array_merge($params, [
                'now_is_makeHtml' => $this->now_is_makeHtml
            ]);
        }
        cache()->Tmp()->Write($this->taskName . '.json', JSON::EnCode($params) . "\r\n", 'makeHtml', false);
        $this->json($params);
    }

    public function ApiByCreateSite()
    {
        $cls_makeHtml = new \PKApp\Site\Classes\MakeHtml();
        $cls_makeHtml->Main();
        $this->json([
            'makeType' => 'site_home',
            'now_is_makeHtml' => true,
        ]);
    }

    public function ApiByCreateSiteMaps()
    {
        // 栏目列表
        $list_category = $this->service_category->GetList();
        Arrays::Is($list_category) ?: $this->noticeByJson('Category_Empty');
        $path_site = $domain = '';
        $this->_getSitePath($path_site, $domain);
        $list_category_tree = $this->treeOfCategory($list_category, 0, $path_site);
        $list_xml = [];
        $now_time = gmdate('c');
        $list_url = $this->getListUrl();
        foreach ($list_url as $index => $item) {
            if (stristr($item, 'index')) {
                continue;
            }
            $item['url'] = $domain . ltrim($item['url'], '/');
            $item['md5'] = md5($item['url']);
            $item['siteId'] = $this->loginUser()->SiteId;
            $list_url[$index] = $item;
            $list_xml[] = ['loc' => $item['url'], 'priority' => (stristr($item['url'], 'index') ? '1.0' : '0.8'),
                'changefreq' => 'Always', 'lastmod' => $now_time];
        }
        $listCatId_noMakeHtml = $this->getListCatIdNoMakeHtml();
        $list_category_ById = Arrays::ItemToKey($list_category, 'id');
        // 模型列表
        $list_model = $this->serviceOfModel()->GetListByType('content', ['id', 'name']);
        !Arrays::Is($list_model) ?: $list_model = Arrays::Column($list_model, 'name', 'id');
        $list_model_content = [];
        foreach ($list_model as $id_model => $name_model) {
            $list_model_content[$id_model] = [
                'name' => $name_model,
                'lists' => []
            ];
            $list_content = $this->serviceOfContent($id_model)->GetList(['siteId' => $this->loginUser()->SiteId],
                ['id', 'catId', 'title', 'url']);
            if (Arrays::Is($list_content)) {
                foreach ($list_content as $entity_content) {
                    if (!in_array($entity_content['catId'], $listCatId_noMakeHtml)) {
                        $entity_category = $list_category_ById[$entity_content['catId']];
                        $templateConfig = $entity_category['template'];
                        if (!Arrays::Is($entity_category)) {
                            continue;
                        }
                        $url = self::UrlPathOfContent($entity_category, $templateConfig,
                            $entity_content, $path_site);
                        $url_domain = $domain . ltrim($url, '/');
                        $list_url[] = ['md5' => md5($url_domain), 'url' => $url_domain,
                            'siteId' => $this->loginUser()->SiteId];
                        $list_model_content[$id_model]['lists'][] = ['title' => $entity_content['title'], 'url' => $url,];
                        $list_xml[] = ['loc' => $url_domain, 'priority' => 0.8,
                            'lastmod' => $now_time, 'changefreq' => 'Always'];
                    }
                }
            }
        }
        $this->_makeSiteMapsByXml($list_xml);
        $this->_isBaiDuPush($list_url);
        $this->assign([
            'categoryList' => $list_category_tree,
            'modelList' => $list_model_content,
        ]);
        fileHelper()->PutContents(PATH_ROOT . $path_site, 'sitemap.htm',
            $this->view()->PhpDisplay('site_map'));
        $this->json([
            'makeType' => 'site_maps',
            'now_is_makeHtml' => true,
        ]);
    }

    private function _isBaiDuPush(array $list_url)
    {
        $id_site = $this->loginUser()->SiteId;
        $dir = 'LogBaiDuPush';
        $file = $id_site . '_' . Date::Format('Y-m-d');
        $listDB_url = $this->serviceOfLogPushBaiDu()->GetList(['md5' => $list_url['md5'],
            'siteId' => $id_site,], ['md5']);
        if (Arrays::Is($listDB_url)) {
            $listDB_url = Arrays::Column($listDB_url, 'md5');
            foreach ($list_url as $index => $item) {
                if (in_array($item, $listDB_url)) {
                    unset($list_url[$index]);
                }
            }
        }
        cache()->Tmp()->WriteByJSON($file, $list_url, $dir);
    }

    private function _makeSiteMapsByXml(array $list_xml)
    {
        $cls_xml = new Xml();
        try {
            fileHelper()->PutContents(PATH_ROOT, 'sitemap.xml',
                $cls_xml->Create('urlset', $list_xml, 'url'));
        } catch (\DOMException $e) {
            handlerException($e);
        }
    }

    private function _getSitePath(string &$site_path, string &$site_domain)
    {
        $siteEntity = $this->serviceOfSite()->interface_getEntityById($this->loginUser()->SiteId, ['Site_Domain', 'Site_Path']);
        $site_path = $siteEntity['Site_Path'];
        $site_domain = $siteEntity['Site_Domain'];
    }

}